/* setecho.c  
 *   用法:  setecho [y|n]  
 *   功能:  显示如何读取、更改和重置终端属性，以控制回显功能  
 */  

#include <stdio.h>  
#include <stdlib.h>  
#include <termios.h>  
#include <unistd.h>  
#include <string.h>  

#define ERR_EXIT(status, msg) do { perror(msg); exit(status); } while(0)  

int main(int argc, char *argv[])  
{  
    struct termios original_attr, new_attr;  

    /* 检查命令行参数数量 */  
    if (argc != 2) {  
        fprintf(stderr, "用法: %s [y|n]\n", argv[0]);  
        exit(EXIT_FAILURE);  
    }  

    /* 获取当前终端属性 */  
    if (tcgetattr(STDIN_FILENO, &original_attr) == -1) {  
        ERR_EXIT(EXIT_FAILURE, "tcgetattr");  
    }  

    /* 复制当前属性，以便进行修改 */  
    new_attr = original_attr;  

    /* 根据用户输入修改 ECHO 标志 */  
    if (argv[1][0] == 'y' || argv[1][0] == 'Y') {  
        new_attr.c_lflag |= ECHO;  /* 开启回显 */  
    }  
    else if (argv[1][0] == 'n' || argv[1][0] == 'N') {  
        new_attr.c_lflag &= ~ECHO; /* 关闭回显 */  
    }  
    else {  
        fprintf(stderr, "无效参数: %s. 请选择 'y' 或 'n'.\n", argv[1]);  
        exit(EXIT_FAILURE);  
    }  

    /* 设置新的终端属性 */  
    if (tcsetattr(STDIN_FILENO, TCSANOW, &new_attr) == -1) {  
        ERR_EXIT(EXIT_FAILURE, "tcsetattr");  
    }  

    /* 提示用户回显状态已更改 */  
    printf("回显已被%s.\n", (argv[1][0] == 'y' || argv[1][0] == 'Y') ? "开启" : "关闭");  

    return EXIT_SUCCESS;  
}